package App.Service;

import App.Model.*;
import App.Model.Account.*;
import App.Model.Version.CrmAppVersion;
import App.Repository.AccountRepository;
import App.Utility.HttpClientUtil;
import App.Utility.JwtAuth;
import App.Utility.RSADecrypt;
import App.Utility.SecurityHash;
import App.Tencent.TLSSigAPIv2;
import com.alibaba.fastjson.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by xw on 2018/11/12.
 */
@Service
public class AccountService {

    private final Log log = LogFactory.getLog(getClass());

    @Autowired
    AccountConfig _accountConfig;

    @Autowired
    private AccountRepository _repository;

    @Autowired
    private JwtAuth _jwtAuth;

    @Autowired
    private TecentIMService _imService;

    private String prikey = "\n" +
            "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALqiTpPKUOkbv7HC\n" +
            "+jgITKBmpBK1YcQZpyCXvHf2Oz5Lki+s77qnIKBzK6Xl71ZaWbSz7Rvaagv9V2U5\n" +
            "bjhIX6n2odfc5+ArMoVxWn9ePPiPX0GtTCFznPmOZhrOlELmYdVTSfLRbsAvHild\n" +
            "nETupA5qj+hmp9iTmQGQ51Zc+I3JAgMBAAECgYAD5goQKkTAadT6SKFjdEDthNde\n" +
            "kK1nJEYKd0D3nIwmQ/vcxRcI5h7XWzCJOaFjQ2XmUW/dihV3BKbDtYxo3pIo+I2S\n" +
            "r30Py8NiRqHjU8szniYRFBr/n6gEu3oGxmiNlUPpfXP2KaG/1yvje0IRjyisBC9Q\n" +
            "OqD75P/xx5DGx8WOkQJBAPVKmEqcb9coD2cKSfsyPXeLKVMgb931a8UUpqx2Hw+R\n" +
            "+vYi9+t7HdrFlxDqk+dtnAKJlmCidJaJb3cq7U0byh0CQQDCyCaAk8D1AykuX4zG\n" +
            "PSSua7U2ENEQlDhsPQYY5Lu3HeB3bzus7w7NkjtRdAQzHStfvDEfabXlh3pBpkes\n" +
            "gOKdAkBdSvfNON6YuJXTHOiyb5NNSlJ3WVjy1IsetBIIegyqQV1wDDC7EWJzeL9S\n" +
            "IcYLOXcix+2351Hsh20rp9oFf9JJAkBVk0vfJ4sZ2haoqhAWNFy+SNHnfAHuD8Cu\n" +
            "RS09mJikPfsVXghQ1QKi7IElKxyBPGqG+A5455+jxR7AYwaQUlu9AkAZltgBdPEZ\n" +
            "6kh314JnXDnxy8K7LPeO/HGh9lUD+0Pc89gJWqJubULKZjJcLZOwLL+vbnGyiyYw\n" +
            "Ujs36CFvXCo9\n" +
            "\n";

    public List<CrmUser> select() {
        return _repository.select();
    }

    public BaseResponse login(LoginRequest _request) {

        String strToken = "";
        String _message = "";
        int _success = BaseEnum.ApiResult.Failure.getApiResult();
        BaseResponse _baseResponse = new BaseResponse();
        _baseResponse.setSuccess(_success);

        try {
            CrmUser currentUser = _repository.selectUser(_request);

            if (currentUser == null) {
                _baseResponse.setMessage("用户名错误");
                return _baseResponse;
            }

            //check user
            String _salt = _accountConfig.getPasswordsalt();
            String securityPassword = SecurityHash.getPwdSecurity(_request.getPassword(), _salt);
            if (!securityPassword.equals(currentUser.getPassword())) {
                _baseResponse.setMessage("用户密码错误");
                return _baseResponse;
            }

            //check user status
            if (currentUser.getRecstatus() == BaseEnum.UserStatus.Disable.getUserStatus()) {

                _baseResponse.setMessage("用户已禁用，不能登陆");
                return _baseResponse;
            }

            int _userId = currentUser.getId();
            String _userName = currentUser.getUsername();

            //生成token

            JWTResponse _jwtResponse = _jwtAuth.buildTokenNew(_userId, _userName);
            String token = _jwtResponse.getToken();
            java.util.Date _expireDate = _jwtResponse.getExpiretionDate();
            strToken = "Bearer " + token;

            _success = BaseEnum.ApiResult.Success.getApiResult();
            _baseResponse.setMessage("登陆成功");
            _baseResponse.setSuccess(_success);

            LoginResponse _loginResponse = new LoginResponse();
            _loginResponse.setToken(strToken);
            _loginResponse.setUserid(_userId);
            // 根据生成的IM用户生成签名
            long SDKAppID = 1400201174;
            String miyao = "5eecdf39b1436a5456fdf2cad98d2695af79b8f5821ccbdc759cbdc5fa69fe94";
//
            //  2022/4/15  失效之前的userSig
            _imService.kickImUser(_userId);

            TLSSigAPIv2 api = new TLSSigAPIv2(SDKAppID, miyao);
            String sign = api.genUserSig(Integer.toString(_userId), 3600 * 24 * 180);
            _loginResponse.setSig(sign);
            String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
            _loginResponse.setServertime(timeStamp);
            _baseResponse.setData(_loginResponse);

            //write token
            _repository.InsertTokenHistory(_userId, token, _expireDate, "");

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            _baseResponse.setData(ex);
            _baseResponse.setMessage("程序报错");
        }
        return _baseResponse;
    }

    public String buildToken(int userId, String userName) {
        Long now = System.currentTimeMillis();
        Claims _claims = Jwts.claims();
        _claims.put("uuid", userId);
        _claims.put("username", userName);
        //   String _secrete =jwtConfig.getSecret();
        String token = Jwts.builder()
                .setSubject(userName)
                .setClaims(_claims)
                .setIssuer("crm")
                .setIssuedAt(new java.util.Date(now))
                .setExpiration(new java.util.Date(System.currentTimeMillis() + 60 * 60 * 24 * 1000))
                .signWith(SignatureAlgorithm.HS256, "MyJwtSecret")
                .compact();
        return token;
    }

    public String login2() {
        String _name = "admin";
        Map<String, Object> _claims = new HashMap<>();
        _claims.put("id", 12);
        _claims.put("name", "lukez");

        Long now = System.currentTimeMillis();

        String token = Jwts.builder()
                .setSubject(_name)
                // Convert to list of strings.
                // This is important because it affects the way we get them back in the Gateway.
                .claim("authorities", "ROLE_ADMIN")
                .setIssuedAt(new Date(now))
                .setExpiration(new Date(now + 24 * 60 * 60 * 1000))  // in milliseconds
                .signWith(SignatureAlgorithm.HS512, "JwtSecretKey".getBytes())
                .compact();

        return "Bearer " + token;
    }

    public String login3(String token) {

        String user = Jwts.parser()
                .setSigningKey("MyJwtSecret")
                .parseClaimsJws(token.replace("Bearer ", ""))
                .getBody()
                .getSubject();

        return user;

    }

    public CrmUser selectUser(LoginRequest _request) {
        return _repository.selectUser(_request);
    }

    public int register(RegisterRequest _request) {
        int result = 0;
        try {

            String orginalPassword = _request.getPassword();
            String _salt = _accountConfig.getPasswordsalt();
            String securityPassword = App.Utility.SecurityHash.getPwdSecurity(orginalPassword, _salt);
            _request.setPassword(securityPassword);
            result = _repository.register(_request);

            if (result > 0) {
                LoginRequest _loginRequest = new LoginRequest();
                _loginRequest.setUsername(_request.getUsername());
                CrmUser _currentUser = _repository.selectUser(_loginRequest);
                if (_currentUser != null) {
                    int _userid = _currentUser.getId();
                    boolean _isSuccess = _imService.accountImport(_userid, _request.getRealname());
                    if (!_isSuccess) {
                        result = 0;
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;

    }

    public int changePassword(ChagePasswordRequest _request) throws Exception {

        String _phone = _request.getPhone();
        String _oldPassword = _request.getOldpassword();
        String _newPassword = _request.getNewpassword();

        String _oldSecurityPassword = "";
        // String _oldSecurityPassword = App.Utility.SecurityHash.getPwdSecurity(_oldPassword, _salt);
        String _salt = _accountConfig.getPasswordsalt();
        String _newSecurityPassword = App.Utility.SecurityHash.getPwdSecurity(_newPassword, _salt);
        int _result = _repository.changePassword(_phone, _oldSecurityPassword, _newSecurityPassword);
        return _result;
    }

    public int updateUserProfile(UpdateUserInfoRequest _request, int userid) {
        return _repository.updateUserProfile(_request, userid);
    }

    public List<CrmDataItem> getLawyerExpertises() {
        return _repository.getLawyerExpertises();
    }

    public int authUser(AuthUserRequest _request, int userid) throws Exception {
        if (_request.getRecid() == null || _request.getRecid().isEmpty()) {
            return _repository.authUser(_request, userid);
        } else {
            return _repository.updateAuthUser(_request, userid);
        }
    }

    public List<AuthUserList> getLawyerAuthList(int userid) {
        return _repository.getLawyerAuthList(userid);
    }

    public AuthUserProcess getLawyerAuthProcess(int userid) {
        return _repository.getLawyerAuthProcess(userid);
    }

    public CrmUserDetail getUserDetail(getUserDetailRequest _request) {
        return _repository.getUserInfo(_request.getUserid());
    }

    public getIMInfoResponse getTencentIMInfo() {
        long _sdkid = _imService.getSDKId();
        int _accountType = _imService.getAccessType();
        getIMInfoResponse _response = new getIMInfoResponse();
        _response.setAccounttype(_accountType);
        _response.setSdkappid(_sdkid);
        return _response;
    }


    public CrmAppVersion getVersionNO(int appType) {
        return _repository.getVersionNO(appType);
    }


    public GetNewTokenResponse getNewToken(String userAuth) {

        String _oldToken = userAuth;
        String _newToken = "";

        CrmUser _theLoginUser = _jwtAuth.getTokenUserInfo(_oldToken);
        String token = _jwtAuth.buildToken(_theLoginUser.getId(), _theLoginUser.getUsername());
        _newToken = "Bearer " + token;

        GetNewTokenResponse _response = new GetNewTokenResponse();
        _response.setToken(_newToken);
        return _response;
    }

    public GetNewTokenResponse getMobileNewToken(String userAuth) {

        String _oldToken = userAuth.replace("Bearer ", "");
        String _newToken = "";

        CrmUser _theLoginUser = _repository.getUserByToken(_oldToken);
        JWTResponse _jwtRespons = _jwtAuth.buildTokenNew(_theLoginUser.getId(), _theLoginUser.getUsername());
        String token = _jwtRespons.getToken();
        if (token != null) {
            java.util.Date _expireDate = _jwtRespons.getExpiretionDate();
            _repository.UpdateTokenValid(_expireDate, token, _oldToken);
        }
        _newToken = "Bearer " + token;

        GetNewTokenResponse _response = new GetNewTokenResponse();
        _response.setToken(_newToken);
        return _response;
    }

    public int InsertTokenHistory(int userid, String token, java.util.Date expiretationDate, String oldToken) {
        return _repository.InsertTokenHistory(userid, token, expiretationDate, oldToken);
    }


    public int UpdateTokenInvalid(String token) {

        return _repository.UpdateTokenInvalid(token);
    }


    public BaseResponse loginForCheckCode(LoginRequest _request) {

        String strToken = "";
        String _message = "";
        int _success = BaseEnum.ApiResult.Failure.getApiResult();
        BaseResponse _baseResponse = new BaseResponse();
        _baseResponse.setSuccess(_success);

        int _userId = 0;
        try {
            CrmUser currentUser = _repository.selectUser(_request);
            //如果系统不存在用户则直接注册
            if (currentUser == null) {
                RegisterRequest req = new RegisterRequest();
                req.setUsername(_request.getUsername());
                req.setRealname(_request.getUsername());

                int result = this.register(req);
                if (result > 0) {
                    currentUser = _repository.selectUser(_request);
                } else {
                    _baseResponse.setMessage("用户注册失败，请联系管理员");
                    return _baseResponse;
                }
            }
            //check user status
            if (currentUser.getRecstatus() == BaseEnum.UserStatus.Disable.getUserStatus()) {

                _baseResponse.setMessage("用户已禁用，不能登陆");
                return _baseResponse;
            }

            _userId = currentUser.getId();
            _baseResponse.setUserid(_userId);

            String _userName = currentUser.getUsername();
            // 2022/4/19 先使原来的token失效, 然后创建新的token
            _repository.UpdateTokenInvalidByUserId(_userId);

            //生成token

            JWTResponse _jwtResponse = _jwtAuth.buildTokenNew(_userId, _userName);
            String token = _jwtResponse.getToken();
            java.util.Date _expireDate = _jwtResponse.getExpiretionDate();
            strToken = "Bearer " + token;

            _success = BaseEnum.ApiResult.Success.getApiResult();
            _baseResponse.setMessage("登陆成功");
            _baseResponse.setSuccess(_success);

            LoginResponse _loginResponse = new LoginResponse();
            _loginResponse.setToken(strToken);
            _loginResponse.setUserid(_userId);
            //力贤测试---
            // 根据生成的IM用户生成签名
            long SDKAppID = 1400201174;
            String miyao = "5eecdf39b1436a5456fdf2cad98d2695af79b8f5821ccbdc759cbdc5fa69fe94";
//
//            long SDKAppID = 1400547306;//力贤测试
//            String miyao = "7ff807c3ca505f4b131bf2a8d70fc77e21502316d60c0a2f68e0b0dcbbecde63";//力贤测试
            TLSSigAPIv2 api = new TLSSigAPIv2(SDKAppID, miyao);
            String sign = api.genUserSig(Integer.toString(_userId), 3600 * 24 * 180);
            _loginResponse.setSig(sign);
            String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
            _loginResponse.setServertime(timeStamp);
            _baseResponse.setData(_loginResponse);

            //write token
            _repository.InsertTokenHistory(_userId, token, _expireDate, "");

        } catch (Exception ex) {
            ex.printStackTrace();
            _baseResponse.setData(ex);
            _baseResponse.setMessage("程序报错");
        }
        return _baseResponse;
    }

    public int insertUserLoginHistory(int userid, String version, int clientType, int loginResult, String optmethod) {
        return _repository.InsertUserLoginHistory(userid, version, clientType, loginResult, optmethod);
    }

    public java.util.Date GetWebLoginTime(int userid){
        return  _repository.GetWebLoginTime(userid);
    }

    /**
     * 一键登陆接口
     *
     * @param request
     * @return
     */
    public Object keyLogin(LoginRequest request) {
        String strToken = "";
        String _message = "";
        int _success = BaseEnum.ApiResult.Failure.getApiResult();
        BaseResponse _baseResponse = new BaseResponse();
        _baseResponse.setSuccess(_success);

        try {
            //调用极光登陆
            String url = "https://api.verification.jpush.cn/v1/web/loginTokenVerify";
            JSONObject param = new JSONObject();
            param.put("loginToken", request.getToken());
            String res = HttpClientUtil.sendPost(url, param.toString());
            log.info("极光返回：" + res);
            JSONObject resJson = JSONObject.parseObject(res);
            //极光返回
            if ("8000".equals(resJson.getString("code"))) {
                String phoneStr = resJson.getString("phone");
                //解析手机号
                log.info("解析手机号phoneStr：" + phoneStr);
                log.info("解析手机号prikey：" + prikey);
                String phone = RSADecrypt.decrypt(phoneStr, prikey);
                request.setUsername(phone);
            } else {
                _baseResponse.setMessage("极光token认证失败");
                return _baseResponse;
            }

            CrmUser currentUser = _repository.selectUser(request);

            //用户注册
            if (currentUser == null) {
                RegisterRequest req = new RegisterRequest();
                req.setUsername(request.getUsername());
                req.setRealname(request.getUsername());

                int result = this.register(req);
                if (result > 0) {
                    currentUser = _repository.selectUser(request);
                } else {
                    _baseResponse.setMessage("用户注册失败，请联系管理员");
                    return _baseResponse;
                }
            }


            //check user status
            if (currentUser.getRecstatus() == BaseEnum.UserStatus.Disable.getUserStatus()) {

                _baseResponse.setMessage("用户已禁用，不能登陆");
                return _baseResponse;
            }

            int _userId = currentUser.getId();
            String _userName = currentUser.getUsername();
            // 2022/4/19 先使原来的token失效, 然后创建新的token
            _repository.UpdateTokenInvalidByUserId(_userId);
            //生成token

            JWTResponse _jwtResponse = _jwtAuth.buildTokenNew(_userId, _userName);
            String token = _jwtResponse.getToken();
            java.util.Date _expireDate = _jwtResponse.getExpiretionDate();
            strToken = "Bearer " + token;

            _success = BaseEnum.ApiResult.Success.getApiResult();
            _baseResponse.setMessage("登陆成功");
            _baseResponse.setSuccess(_success);

            LoginResponse _loginResponse = new LoginResponse();
            _loginResponse.setToken(strToken);
            _loginResponse.setUserid(_userId);
            _loginResponse.setPhone(currentUser.getUsername());
            // 根据生成的IM用户生成签名
            long SDKAppID = 1400201174;
            String miyao = "5eecdf39b1436a5456fdf2cad98d2695af79b8f5821ccbdc759cbdc5fa69fe94";
//

            TLSSigAPIv2 api = new TLSSigAPIv2(SDKAppID, miyao);
            String sign = api.genUserSig(Integer.toString(_userId), 3600 * 24 * 180);
            _loginResponse.setSig(sign);
            String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
            _loginResponse.setServertime(timeStamp);
            _baseResponse.setData(_loginResponse);

            //write token
            _repository.InsertTokenHistory(_userId, token, _expireDate, "");

        } catch (Exception ex) {
            System.out.println(ex.getMessage());
            _baseResponse.setData(ex);
            _baseResponse.setMessage("程序报错");
        }
        return _baseResponse;
    }

    public void cancellation(int userId) {
        _repository.updateIslogin(userId);
    }

    public Object getToken(String phone) {
        CrmUserDetail _theLoginUser = _repository.getUserInfoByPhone(phone);
        CrmToken crmToken = _repository.GetTokensByUserId(_theLoginUser.getUserid());
        int _success = BaseEnum.ApiResult.Failure.getApiResult();
        BaseResponse _baseResponse = new BaseResponse();
        _baseResponse.setSuccess(_success);
        _baseResponse.setMessage("获取token成功");
        _baseResponse.setData("Bearer " + crmToken.getToken());
        return _baseResponse;
    }


    public boolean checkToken(CheckTokenRequest request) {
        return _repository.IsTokenValid(request.getToken());
    }

    public String shopGetToken(String phone) {
        CrmToken token = _repository.getTokenByUserName(phone);
        if (null != token) {
            return token.getToken();
        }
        return null;
    }

    public String getTokenByOldToken(String oldToken) {
        String _oldToken = oldToken.replace("Bearer ", "");
        CrmUser userInfo = _repository.getUserByToken(_oldToken);
        CrmToken crmToken = _repository.getTokenByUserId(userInfo.getId());
        if (!_oldToken.equals(crmToken.getToken())) {
            return null;
        }
        //失效token
        _repository.UpdateTokenInvalidByUserId(userInfo.getId());
        //生成token
        JWTResponse _jwtResponse = _jwtAuth.buildTokenNew(userInfo.getId(), userInfo.getUsername());
        String token = _jwtResponse.getToken();
        java.util.Date _expireDate = _jwtResponse.getExpiretionDate();
        String newToken = "Bearer " + token;
        //write token
        _repository.InsertTokenHistory(userInfo.getId(), token, _expireDate, "");
        return newToken;
    }
}
